package com.easy.zhihu.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.easy.commons.utils.http.HttpService;
import com.easy.commons.utils.http.handler.DefaultResulthandler;
import com.easy.zhihu.constant.ZhihuApiConstant;
import com.easy.zhihu.dao.AnswerRepository;
import com.easy.zhihu.dao.HotWordRepository;
import com.easy.zhihu.dao.WishesRepository;
import com.easy.zhihu.pojo.Answer;
import com.easy.zhihu.pojo.EasyWord;
import com.easy.zhihu.pojo.HotWords;
import com.easy.zhihu.pojo.Wishes;
import com.easy.zhihu.service.ZhihuService;
import com.easy.zhihu.util.HtmlFormat;
import com.easy.zhihu.util.LoadDic;
import org.apdplat.word.WordSegmenter;
import org.apdplat.word.segmentation.PartOfSpeech;
import org.apdplat.word.segmentation.SegmentationAlgorithm;
import org.apdplat.word.segmentation.Word;
import org.apdplat.word.tagging.PartOfSpeechTagging;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Packge com.easy.zhihu.service.impl
 * @Autor linNaibin
 * @Description
 * @Version 1.0
 * @Date 2021/3/16 15:36
 */
@Service
public class ZhihuServiceImpl implements ZhihuService {

    private HotWordRepository hotWordRepository;

    private AnswerRepository answerRepository;

    private WishesRepository wishesRepository;

    private RestTemplate restTemplate;

    @Autowired
    public ZhihuServiceImpl(RestTemplate restTemplate, HotWordRepository hotWordRepository, AnswerRepository answerRepository, WishesRepository wishesRepository) {
        this.hotWordRepository = hotWordRepository;
        this.answerRepository = answerRepository;
        this.wishesRepository = wishesRepository;
        this.restTemplate = restTemplate;
        LoadDic loadDic = LoadDic.getInstance();
    }


    //
    @Transactional
    @Override
    public void executor(int total) {

        // 计算一共有多少页
        int remainder = total % 20;
        int quotient = total / 20;

        int pageNum = remainder > 0 ? (quotient + 1) : quotient;

        for (int i = 0; i <= pageNum; i++) {

            int offset = (i) * 20;

            String ret = HttpService.httpGet(ZhihuApiConstant.getAnswerList(offset), new DefaultResulthandler());

            JSONObject resultJson = JSONObject.parseObject(ret);

            JSONArray array = resultJson.getJSONArray("data");

            // 得到 一个 answer id 集合
            List<String> idArray = array.stream().map(obj -> {
                JSONObject jsonObject = (JSONObject) obj;
                String id = jsonObject.getString("id");
                return id;
            }).collect(Collectors.toList());

            answerProcessor(idArray);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }


        List<HotWords> hotWordsList = hotWordRepository.findAll();
        hotWordsList.forEach(System.out::println);
    }


    // 2022 知乎更改了   请求方式
    @Override
    public void executor() {
        String QUESTIONS_NUMBER = "318020899";
        String ANSWER_URL = "https://www.zhihu.com/api/v4/questions/" + QUESTIONS_NUMBER + "/feeds?include=data[*].content&offset=0&limit=10&platform=desktop";

        System.out.println(ANSWER_URL);
        ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(ANSWER_URL, JSONObject.class);

        System.out.println(responseEntity.getBody());

    }

    private void answerProcessor(List<String> idArray) {

        int errorCount = 0;
        int continueCount = 0;

        for (int z = 0; z < idArray.size(); z++) {

            String id = idArray.get(z);
            try {
                // http send
                String url = ZhihuApiConstant.getAnswerDetail(id);
                System.out.println("request url >>" + url);
                ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(url, JSONObject.class);

                // String ret = HttpService.httpGet(ZhihuApiConstant.getAnswerDetail(id), new DefaultResulthandler());

                // JSONObject resultJson = JSONObject.parseObject(ret);
                JSONObject resultJson = responseEntity.getBody();
                System.out.println(responseEntity.getBody());

                Answer answer = new Answer();
                //
                answer.setAId(id);
                //
                String content = HtmlFormat.getTextFromHtml(resultJson.getString("content"));

                answer.setContent(content);
                Integer isexit = answerRepository.findNum(answer.getContent());
                if (isexit != null && isexit > 0) {
                    continueCount++;
                    continue;
                }
                // System.out.println("文本内容：\n" + content);
                // author
                JSONObject author = resultJson.getJSONObject("author");
                answer.setName(author.getString("name"));
                answer.setUrlToken(author.getString("url_token"));

                // 分词
                //  List<Word> list = WordSegmenter.seg(content);
                // 词性标注 , SegmentationAlgorithm.MinimalWordCount
                //  PartOfSpeechTagging.process(list);

                List<EasyWord> list = null;
                try {
                    list = segmentIK(content);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                answer.setSex(1);
                // 取 70% 是描述自己的
                int me = (int) (list.size() * 0.7);

                for (int i = 0; i < me; i++) {

                    EasyWord word = list.get(i);

                    // 年龄
                    if (word.getType() == 10003) {
                        Integer age = Integer.valueOf(word.getText());
                        if (age >= 18 && age <= 60) {
                            answer.setAge(age);
                        }
                    } else if (word.getType() == 10002) {
                        // 身高
                        answer.setHeight(word.getText());
                    } else if (word.getType() == 10001) {
                        // 体重
                        answer.setWeight(word.getText());
                    } else if (word.getType() == 10006) {
                        answer.setSex(1);
                    } else if (word.getType() == 10007) {
                        answer.setSex(2);
                    } else if (word.getType() == 10004) {
                        // 所在地
                        answer.setRegion(word.getText());

                    } else if (word.getType() == 10005) {
                        // 职业
                        answer.setDemand(word.getText());
                    } else if (word.getType() == 10008) {
                        //  学历
                        answer.setResume(word.getText());
                    } else {

                        //
                        HotWords hotWords = new HotWords();
                        hotWords.setWord(word.getText());
                        Integer num = hotWordRepository.findNum(word.getText(), answer.getSex());
                        if (num != null) {
                            hotWordRepository.addNum(hotWords.getWord(), answer.getSex());
                        } else {
                            hotWords.setSex(answer.getSex());
                            hotWords.setNum(1);
                            // add
                            hotWordRepository.save(hotWords);

                        }
                    }

                }

                // 期望
                for (int i = me; i < list.size(); i++) {

                    EasyWord word = list.get(i);
                    // 对对方的要求
                    // 记入 wishes
                    if (word.getType() == 4) {
                        Wishes wishes = new Wishes();
                        wishes.setWord(word.getText());
                        Integer num = wishesRepository.findNum(wishes.getWord(), answer.getSex());
                        if (num != null) {
                            wishesRepository.addNum(word.getText(), answer.getSex());
                        } else {
                            wishes.setSex(answer.getSex());
                            wishes.setNum(1);
                            // add

                            wishesRepository.save(wishes);

                        }

                    }

                    //


                }

                //
                // save
                answerRepository.save(answer);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                errorCount++;
                continue;
            }

        }
        System.out.println("执行完毕，错误：" + errorCount + ",重复：" + continueCount);

    }

    // ik 分词
    public List<EasyWord> segmentIK(String text) throws Exception { //text 为你要搜索的内容

        List<EasyWord> set = new ArrayList<>();

        StringReader re = new StringReader(text.trim());

        IKSegmenter ik = new IKSegmenter(re, true);

        Lexeme lex;

        while ((lex = ik.next()) != null) {

            if (lex.getLexemeText().length() < 2) {
                continue;
            }
            System.out.println("word:" + lex.getLexemeText() + ",type:" + lex.getLexemeType() + ",desc:" + lex.getLexemeTypeString());
            EasyWord word = new EasyWord();
            word.setText(lex.getLexemeText());
            word.setType(lex.getLexemeType());

            try {
                // 量词
                if (word.getType() == 2) {
                    // 体重 小于 150
                    Integer i = Integer.valueOf(word.getText());
                    if (i > 40 && i <= 150) {
                        // 一般是体重
                        word.setType(10001);
                    } else if (i > 149 && i < 190) {
                        // 身高
                        word.setType(10002);
                    }

                    set.add(word);
                    continue;
                }

                // 对单位
                if (word.getType() == 48) {

                    // 拿到最后一个词
                    String dw = word.getText().substring(word.getText().length() - 1, word.getText().length());
                    String s = word.getText().replace(dw, "");
                    // 年
                    if (dw.equals("年")) {

                        Integer a = Integer.valueOf(s);
                        if (s.length() == 2) {
                            // 年份
                            Integer me;
                            if (a > 60) {
                                me = Integer.valueOf("19" + s);
                            } else {
                                me = Integer.valueOf("20" + s);
                            }
                            Integer nowYear = 2021;
                            word.setText((nowYear - me) + "");
                            word.setType(10003);

                        }

                    } else if (dw.equals("岁")) {
                        word.setText(word.getText().replace(dw, ""));
                        word.setType(10003);
                    } else if (dw.equals("斤")) {
                        word.setText(word.getText().replace(dw, ""));
                        word.setType(10001);
                    }
                    set.add(word);
                    continue;

                }

                // TYPE_CQUAN
                if (word.getType() == 3) {
                    // 年份之类的,年龄,身高
                    Integer a = Integer.valueOf(word.getText());
                    word.setType(10003);

                    if (word.getText().length() == 2 && a <= 50) {
                        // 年龄
                        set.add(word);
                        continue;
                    }
                    if (word.getText().length() == 4) {
                        // 年份
                        Integer nowYear = 2021;
                        word.setText((nowYear - a) + "");
                        set.add(word);
                        continue;
                    }
                    if (word.getText().length() == 2) {
                        // 年份
                        Integer me;
                        if (a > 60) {
                            me = Integer.valueOf("19" + word.getText());
                        } else {
                            me = Integer.valueOf("20" + word.getText());
                        }
                        Integer nowYear = 2021;
                        word.setText((nowYear - me) + "");

                        //
                        if (Integer.valueOf(word.getText()) > 149 && Integer.valueOf(word.getText()) <= 190) {
                            word.setText(lex.getLexemeText());
                            word.setType(10002);
                            // 原始属性
                            continue;
                        }
                        set.add(word);
                        continue;
                    }
                }


                // 职业
                if (word.getType() == 4) {
                    //
                    if (LoadDic.CITY.get(word.getText()) != null) {
                        // 城市
                        word.setType(10004);
                    } else if (LoadDic.ZY.get(word.getText()) != null) {
                        // 职业
                        word.setType(10005);
                    } else if (word.getText().contains("男")) {
                        word.setType(10006);
                    } else if (word.getText().contains("女")) {
                        word.setType(10007);
                    } else if (LoadDic.XL.get(word.getText()) != null) {
                        // 学历
                        word.setType(10008);
                    }
                    set.add(word);

                }


            } catch (Exception e) {
                continue;
            }

            // ARABIC 年份
            // LETTER 可能是身高 ， 带单位的词语
            // CN_WORD 词语

        }

        return set;

    }

}
